home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 June: Reference Library / Dev.CD Jun 99 RL Disk 1.toast / What's New / Development Kits / Mac_OS_USB_DDK_v1.2 / Examples / USBModem / ShimSerialHAL.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-15  |  21.0 KB  |  913 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ShimSerialHAL.c
  3.  
  4.     Contains:    Routines for controlling the underlying hardware (HAL - Hardware Abstraction Layer)
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.  
  9.  
  10.     Copyright:    © 1994-1998 by Apple Computer, Inc., all rights reserved.
  11.  
  12. */
  13.  
  14. #include    <Gestalt.h>
  15. #include    <Errors.h>
  16.  
  17. #include    "Modem.h"
  18. #include    "ShimSerialHAL.h"
  19. #include    "ModemDriver.h"
  20.  
  21. /************************************************************************************/
  22. //
  23. //    SerHAL_Entry
  24. //
  25. //    This is the main driver entry point.
  26. //
  27. /************************************************************************************/
  28.  
  29. OSErr SerHAL_Entry(UInt16 HdwSelector, ParmBlkPtr pb, UInt32 RefCon)
  30. {
  31. #pragma unused (RefCon)
  32.     OSErr    err = noErr;
  33.     
  34.     switch (HdwSelector)
  35.         {
  36.             case SerHAL_Initialize:
  37.                 // only do the open stuff once per driver pair
  38.                 if (gGlobals->openSession == false)
  39.                      err = HAL_DoOpenSession();
  40.                 break;
  41.                 
  42.             case SerHAL_Terminate:
  43.                 // only do the close stuff once per driver pair
  44.                 if (gGlobals->openSession)
  45.                     err = HAL_DoCloseSession();
  46.                 break;
  47.                 
  48.             case SerHAL_Read:
  49.                 //    attempt to fill read request immediately
  50.                 //    from any pending data in the input buffer
  51.                 err = HAL_FillReadRequest((IOParam*)pb);
  52.                 HAL_InputFlowControl();
  53.                 //    if it's not completed (pending) save the pb
  54.                 if (err > noErr)
  55.                     gGlobals->pbIn = pb;
  56.                 break;
  57.                 
  58.             case SerHAL_Write:
  59.                 err = USBSerialWrite((IOParam*)pb);
  60.                 if (err > noErr)
  61.                     gGlobals->pbOut = pb;
  62.                 break;
  63.                 
  64.             case SerHAL_SetConfiguration:
  65.                 err = HAL_SetConfiguration(*(UInt16*)pb->cntrlParam.csParam);
  66.                 break;
  67.                 
  68.             case SerHAL_SetInputBuffer:
  69.                 err = HAL_SetInputBuffer(*(Ptr*)pb->cntrlParam.csParam, *(UInt16*)(((Ptr)pb->cntrlParam.csParam) + 4));
  70.                 break;
  71.                 
  72.             case SerHAL_SetFlowControl:
  73.                 HAL_SetFlowControl((SerShk*)pb->cntrlParam.csParam, pb->cntrlParam.csCode);
  74.                 break;
  75.                 
  76.             case SerHAL_SetBreak:
  77.                 USBSendBreak((pb->cntrlParam.csCode == kSERDSetBreak));
  78.                 break;
  79.                 
  80.             case SerHAL_SetDTERate:
  81.                 // check csCode first to see what the real rate is
  82.                 if (pb->cntrlParam.csCode == kSERD115KBaud)
  83.                 {
  84.                     *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(115200);
  85.                 } else {
  86.                     if (pb->cntrlParam.csCode == kSERD230KBaud)
  87.                     {
  88.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(23400);
  89.  
  90.                     } else {
  91.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(*(UInt16*)pb->cntrlParam.csParam);
  92.                     }
  93.                 }            
  94.                 break;
  95.                 
  96.             case SerHAL_SetDTR:
  97.                 USBSetDTRState((pb->cntrlParam.csCode == kSERDAssertDTR));
  98.                 USBSetControlLineState();
  99.                 break;
  100.                 
  101.             case SerHAL_SetParity:
  102.                 HAL_SetParity((pb->cntrlParam.csCode == kSERDSetPEAltChar), *(unsigned char*)pb->cntrlParam.csParam, *(((unsigned char*)pb->cntrlParam.csParam)+1));
  103.                 break;
  104.                 
  105.             case SerHAL_SetXOffFlag:
  106.                 HAL_SetXOffFlag(pb->cntrlParam.csCode == kSERDSetXOffFlag);
  107.                 break;
  108.                 
  109.             case SerHAL_SendXOn:
  110.                 HAL_SendXOn((pb->cntrlParam.csCode == kSERDSendXOn));
  111.                 break;
  112.                 
  113.             case SerHAL_SendXOff:
  114.                 HAL_SendXOff((pb->cntrlParam.csCode == kSERDSendXOff));
  115.                 break;
  116.                 
  117.             case SerHAL_Miscellaneous:
  118.                 // only interested in DTR (for now)
  119.                 if ((UInt8)pb->cntrlParam.csParam[0] & kOptionPreserveDTR) 
  120.                 {
  121.                     USBSetCloseDTR();
  122.                 }
  123.                 break;
  124.                 
  125.             case SerHAL_GetBuffer:
  126.                 *(UInt32*)(&pb->cntrlParam.csParam[0]) = HAL_GetBuffer();
  127.                 break;
  128.                 
  129.             case SerHAL_GetStatus:
  130.                 HAL_GetStatus((SerStaRec*)pb->cntrlParam.csParam);
  131.                 break;
  132.                 
  133.             case SerHAL_GetVersion:
  134.                 // need to understand this - 9 implies that we do > 57.6K
  135.                 *(char *)pb->cntrlParam.csParam = 9;
  136.                 break;
  137.                 
  138.             case SerHAL_ControlExtend:
  139.                 err = HAL_ControlExtend(pb);
  140.                 break;
  141.                 
  142.             case SerHAL_StatusExtend:
  143.                 err = HAL_StatusExtend(pb);
  144.                 break;
  145.                 
  146.             default:
  147.                 err = -1;                // unknown selector (for now)
  148.                 break;
  149.         }
  150.     
  151.     return err;
  152. }
  153.  
  154. /************************************************************************************/
  155. //
  156. //    HAL_SetConfiguration
  157. //
  158. //    Serial driver SerReset control call.
  159. //
  160. /************************************************************************************/
  161.  
  162. OSErr HAL_SetConfiguration(UInt16 config)
  163. {
  164.  
  165.     UInt16        baudRate;
  166.     LineParms    Line_Coding;
  167.  
  168.     TraceMessage(0,"\pEntering HAL_SetConfiguration");
  169.     
  170.     switch (config & kSerConfigBaudMask)
  171.     {
  172.         case baud300: baudRate = 300; break;
  173.         case baud600: baudRate = 600; break;
  174.         case baud1200: baudRate = 1200; break;
  175.         case baud1800: baudRate = 1800; break;
  176.         case baud2400: baudRate = 2400; break;
  177.         case baud3600: baudRate = 3600; break;
  178.         case baud4800: baudRate = 4800; break;
  179.         case baud7200: baudRate = 7200; break;
  180.         case baud9600: baudRate = 9600; break;
  181.         case baud19200: baudRate = 19200; break;
  182.         case baud38400: baudRate = 38400; break;
  183.         case baud57600: baudRate = 57600; break;
  184.         default: baudRate = 57600; break;
  185.     }
  186.         
  187.     Line_Coding.DTERate1 = USBToHostWord(baudRate);        // All because of Intel format
  188.     Line_Coding.DTERate2 = 0;
  189.     
  190.     switch (config & kSerConfigLenMask)
  191.     {
  192.         case data5: 
  193.             Line_Coding.DataBits = k5DataBits;
  194.             break;
  195.         case data6: 
  196.             Line_Coding.DataBits = k6DataBits;
  197.             break;
  198.         case data7: 
  199.             Line_Coding.DataBits = k7DataBits;
  200.             break;
  201.         case data8: 
  202.             Line_Coding.DataBits = k8DataBits;
  203.             break;
  204.         default: 
  205.             Line_Coding.DataBits = k8DataBits;
  206.             break;
  207.     }
  208.     
  209.     switch (config & kSerConfigParityMask)
  210.     {
  211.         case noParity: 
  212.             Line_Coding.ParityType = kNoParity;
  213.             break;
  214.         case oddParity: 
  215.             Line_Coding.ParityType = kOddParity;
  216.             break;
  217.         case evenParity: 
  218.             Line_Coding.ParityType = kEvenParity;
  219.             break;
  220.         default: 
  221.             Line_Coding.ParityType = kNoParity;
  222.             break;
  223.     }
  224.     
  225.     switch (config & kSerConfigStopMask)
  226.     {
  227.         case stop10: 
  228.             Line_Coding.CharFormat = k1StopBit;
  229.             break;
  230.         case stop15: 
  231.             Line_Coding.CharFormat = k15StopBits;
  232.             break;
  233.         case stop20: 
  234.             Line_Coding.CharFormat = k2StopBits;
  235.             break;
  236.         default: 
  237.             Line_Coding.CharFormat = k1StopBit;
  238.             break;
  239.     }
  240.     
  241.     //    reset the baud rate and other values
  242.  
  243.     USBSetLineCoding(Line_Coding);
  244.  
  245.     return noErr;
  246. }
  247.  
  248. /************************************************************************************/
  249. //
  250. //    HAL_SetInputBuffer
  251. //
  252. //    Select and initialize the serial input buffer.
  253. //
  254. /************************************************************************************/
  255.  
  256. OSErr HAL_SetInputBuffer(Ptr newBuf, UInt16 bufLen)
  257. {
  258.     OSErr    err;
  259.     long    result;
  260.     Boolean    vmPresent;
  261.         
  262.     TraceMessage(0,"\pEntering HAL_SetInputBuffer");
  263.     
  264.     //  check for presence of virtual memory
  265.     
  266.     err = Gestalt(gestaltVMAttr,&result);
  267.     vmPresent = ((err == noErr) && (result >= gestaltVMPresent));
  268.     
  269.     //  un-hold any previous input buffer
  270.     
  271.     if (vmPresent && gGlobals->inBufPtr && (gGlobals->inBufPtr != gGlobals->builtInBuffer))
  272.         UnholdMemory(gGlobals->inBufPtr, gGlobals->inBufLen);
  273.     
  274.     //    assign our local buffer as the default
  275.     
  276.     gGlobals->inBufPtr = gGlobals->builtInBuffer;
  277.     gGlobals->inBufLen = kBuiltInBufferSize;
  278.     
  279.     //    reset buffer indexes
  280.     
  281.     gGlobals->inBufStartIndex = 0;
  282.     gGlobals->inBufEndIndex = 0;
  283.         
  284.     //    a non-zero buffer length means use client buffer
  285.     //    a zero buffer length means use the default buffer
  286.     
  287.     if (bufLen && newBuf)
  288.     {
  289.         //  we need to make sure the buffer stays in physical memory
  290.         
  291.         if (vmPresent)
  292.         {
  293.             err = HoldMemory(newBuf, bufLen);
  294.             if (err != noErr)
  295.                 return err;
  296.         }
  297.         
  298.         //    assign client buffer
  299.         gGlobals->inBufPtr = (UInt8 *) newBuf;
  300.         gGlobals->inBufLen = bufLen;
  301.     }
  302.     
  303.     return noErr;
  304. }
  305.  
  306. /************************************************************************************/
  307. //
  308. //    HAL_SetFlowControl
  309. //
  310. //    Process the csSerHShake & csSerHShakeDTR control calls.
  311. //
  312. /************************************************************************************/
  313.  
  314. void HAL_SetFlowControl(SerShk *shkNew, UInt16 csCode)
  315. {
  316.     
  317.     TraceMessage(0,"\pEntering HAL_SetFlowControl");
  318.     
  319.     //
  320.     //    set new cts value
  321.     //
  322.  
  323.     gGlobals->serShk.fCTS = shkNew->fCTS;
  324.  
  325.     //
  326.     //    copy over new xon / xoff characters
  327.     //
  328.  
  329.     gGlobals->serShk.xOn = shkNew->xOn;
  330.     gGlobals->serShk.xOff = shkNew->xOff;
  331.  
  332.     //
  333.     //    handle any change in software output flow control
  334.     //    this is ignored for now
  335.  
  336.     gGlobals->serShk.fXOn = 0;
  337.  
  338.     //    copy over the errs & evts options fields
  339.     //    notice we do _nada_ with the events (no _PostEvent, etc.)
  340.     
  341.     gGlobals->serShk.errs = shkNew->errs & (parityErr | hwOverrunErr | framingErr);
  342.     gGlobals->serShk.evts = shkNew->evts;
  343.  
  344.     //    handle any change in software input flow control
  345.     //    again this is ignored for now
  346.  
  347.     gGlobals->serShk.fInX = 0;
  348.  
  349.     //    if csCode is newer kSERDHandshake,
  350.     //    take account of the fDTR field
  351.  
  352.     if (csCode == kSERDHandshake)
  353.     {
  354.         
  355.         //
  356.         //    handle any change in hardware input flow control
  357.         //    ignored for now
  358.         //
  359.  
  360.         gGlobals->serShk.fDTR = 1;
  361.  
  362.     }
  363. }
  364.  
  365. /************************************************************************************/
  366. //
  367. //    HAL_SendXOn
  368. //
  369. //    Determines whether to send XOn character.
  370. //    This is a stub for now
  371. //
  372. /************************************************************************************/
  373.  
  374. void HAL_SendXOn(Boolean always)
  375. {
  376. #pragma unused (always)
  377.  
  378.     TraceMessage(0,"\pEntering HAL_SendXOn");
  379.     
  380. }
  381.  
  382. /************************************************************************************/
  383. //
  384. //    HAL_SendXOff
  385. //
  386. //    Determines whether to send XOff character.
  387. //    This is a stub for now
  388. //
  389. /************************************************************************************/
  390.  
  391. void HAL_SendXOff(Boolean always)
  392. {
  393. #pragma unused (always)
  394.  
  395.     TraceMessage(0,"\pEntering HAL_SendXOff");
  396.  
  397. }
  398.  
  399. /************************************************************************************/
  400. //
  401. //    HAL_SendXOffFlag
  402. //
  403. //    Determines whether to send XOff character.
  404. //
  405. /************************************************************************************/
  406.  
  407. void HAL_SetXOffFlag(Boolean state)
  408. {
  409. #pragma unused (state)
  410.  
  411.     TraceMessage(0,"\pEntering HAL_SetXOffFlag");
  412.     
  413.     gGlobals->serStat.xOffHold = 0;            // always off for now
  414.     
  415. }
  416.  
  417. /************************************************************************************/
  418. //
  419. //    HAL_GetStatus
  420. //
  421. //    Status routine fills in the SerStaRec record.
  422. //
  423. /************************************************************************************/
  424.  
  425. void HAL_GetStatus(SerStaRec *statRec)
  426. {
  427.     
  428.     TraceMessage(0,"\pEntering HAL_GetStatus");
  429.     
  430.     //    get & reset cumErrs
  431.     
  432.     statRec->cumErrs = gGlobals->serStat.cumErrs;
  433.     gGlobals->serStat.cumErrs = 0;
  434.  
  435.     //    has an xOff been sent to stop input?
  436.  
  437.     statRec->xOffSent = gGlobals->serStat.xOffSent;  
  438.  
  439.     //    is there a pending read request? 
  440.  
  441.     statRec->rdPend = (gGlobals->pbIn != nil);
  442.  
  443.     //    is there a pending write request?
  444.  
  445.     statRec->wrPend = (gGlobals->pbOut != nil);
  446.  
  447.     //    cts & xOff output flow control hold flags
  448.  
  449.     statRec->ctsHold = false;                    // always false for now?
  450.     statRec->xOffHold = gGlobals->serStat.xOffHold; 
  451.     
  452. }
  453.  
  454. /************************************************************************************/
  455. //
  456. //    HAL_GetBuffer
  457. //
  458. //    status routine computes & returns the number of bytes pending in the receive buffer 
  459. //
  460. /************************************************************************************/
  461.  
  462. UInt32 HAL_GetBuffer(void)
  463. {
  464.     SInt32    count;
  465.     
  466. //    TraceMessage(0,"\pEntering HAL_GetBuffer");
  467.     
  468.     count = ((SInt32)gGlobals->inBufEndIndex - (SInt32)gGlobals->inBufStartIndex);
  469.     
  470.     if ( count < 0 ) 
  471.         count += gGlobals->inBufLen;
  472.             
  473.     return count;
  474. }
  475.  
  476. /************************************************************************************/
  477. //
  478. //    HAL_SetDTERate
  479. //
  480. /************************************************************************************/
  481.  
  482. UInt16 HAL_SetDTERate(UInt32 baudRate)
  483. {
  484.  
  485.     TraceMessage(0,"\pEntering HAL_SetDTERate");
  486.     
  487.     //    validate the requested baud rate
  488.     
  489.     if (baudRate)
  490.     {
  491.         if (baudRate > kMaxBaudRate)
  492.             baudRate = kMaxBaudRate;
  493.             
  494.         gGlobals->baudRate = baudRate;
  495.     } else {
  496.         baudRate = gGlobals->baudRate;
  497.     }
  498.     
  499.     USBSetBaudRate(baudRate);
  500.     
  501.     //    return actual baud rate used (this is historical)
  502.  
  503.     return baudRate;
  504. }
  505.  
  506. /************************************************************************************/
  507. //
  508. //    HAL_SetParity
  509. //
  510. //    Assigns parity error replacement character and alternate replacment character.
  511. //    if peChar is zero then no parity error character substitution.
  512. //    This is a stub for now
  513. //
  514. /************************************************************************************/
  515.  
  516. void HAL_SetParity(Boolean alt, char peChar, char peAltChar)
  517. {
  518. #pragma unused (alt, peChar, peAltChar)
  519.  
  520.     TraceMessage(0,"\pEntering HAL_SetParity");
  521.  
  522. }
  523.  
  524. /************************************************************************************/
  525. //
  526. //    HAL_FillReadRequest
  527. //
  528. //    Attempts to copy requested bytes from the internal serial buffer into request 
  529. //    parameter block.
  530. //
  531. /************************************************************************************/
  532.  
  533. OSErr HAL_FillReadRequest(IOParam *pb)
  534. {
  535.     OSErr    result;
  536.     UInt16    endIndex;
  537.     UInt16    startIndex;
  538.  
  539.     TraceMessage(0,"\pEntering HAL_FillReadRequest");
  540.  
  541.     result = 1;
  542.     while (result > noErr)
  543.     {
  544.  
  545.         //    this can be interrupted to add data to the internal buffer
  546.         //    so we update inBufStartIndex and inBufEndIndex each time
  547.         //    if there is nothing in the input buffer, leave quietly
  548.  
  549.         endIndex = gGlobals->inBufEndIndex;
  550.         startIndex = gGlobals->inBufStartIndex;
  551.         
  552.         if (startIndex == endIndex) 
  553.             break;
  554.  
  555.         //    copy byte into read request buffer and bump actual count
  556.  
  557.         pb->ioBuffer[pb->ioActCount] = gGlobals->inBufPtr[startIndex];
  558.         pb->ioActCount++;
  559.  
  560.         //    now update internal buffer inBufStartIndex
  561.  
  562.         startIndex++;
  563.         
  564.         if (startIndex >= gGlobals->inBufLen) 
  565.             startIndex = 0;
  566.             
  567.         gGlobals->inBufStartIndex = startIndex;
  568.  
  569.         //    lastly, check if we've satisfied the request
  570.  
  571.         if (pb->ioReqCount <= pb->ioActCount)
  572.             result = noErr;
  573.     }
  574.  
  575.     return result;
  576. }
  577.  
  578. /************************************************************************************/
  579. //
  580. //    HAL_EnableSerialDevice
  581. //
  582. //    Called once at driver open time to configure the hardware and get things going etc.
  583. //
  584. /************************************************************************************/
  585.  
  586. void HAL_EnableSerialDevice(void)
  587. {    
  588.     
  589.     TraceMessage(0,"\pEntering HAL_EnableSerialDevice");
  590.     
  591.     USBSetRTSState(1);
  592.     USBSetDTRState(1);
  593.     
  594.     USBSetControlLineState();
  595.     
  596.     HAL_SetDTERate(0);
  597.  
  598.     // Start the read mechanism
  599.     
  600.     USBStartReadPolling();
  601.     
  602. }
  603.  
  604. /************************************************************************************/
  605. //
  606. //    HAL_DisableSerialDevice
  607. //
  608. //    Called once when the driver is closed to shut things down
  609. //
  610. /************************************************************************************/
  611.  
  612. void HAL_DisableSerialDevice(void)
  613. {
  614.     
  615.     TraceMessage(0,"\pEntering HAL_DisableSerialDevice");
  616.  
  617.     USBStopReadPolling();
  618.  
  619.     USBSetRTSState(0);
  620.     USBSetDTRState(0);
  621.     
  622.     USBSetControlLineState();
  623.     
  624. }
  625.  
  626. /************************************************************************************/
  627. //
  628. //    HAL_InputFlowControl
  629. //
  630. //    Handles hardware (dtr or rts) and software (xon / xoff) input flow control
  631. //    This is a stub for now
  632. //
  633. /************************************************************************************/
  634.  
  635. void HAL_InputFlowControl(void)
  636. {
  637.  
  638.     TraceMessage(0,"\pEntering HAL_InputFlowControl");
  639.  
  640. }
  641.  
  642. /************************************************************************************/
  643. //
  644. //    HAL_EnableInput
  645. //
  646. //    Sets the DTR state
  647. //    This is a stub for now
  648. //
  649. /************************************************************************************/
  650.  
  651. void HAL_EnableInput(Boolean enable)
  652. {
  653. #pragma unused (enable)
  654.  
  655.     TraceMessage(0,"\pEntering HAL_EnableInput");
  656.  
  657. }
  658.  
  659. /************************************************************************************/
  660. //
  661. //    HAL_EnableOutput
  662. //
  663. //    Handles output flow control
  664. //    This is a stub for now
  665. //
  666. /************************************************************************************/
  667.  
  668. void HAL_EnableOutput(void)
  669. {
  670.  
  671.     TraceMessage(0,"\pEntering HAL_EnableOutput");
  672.     
  673. }
  674.  
  675. /************************************************************************************/
  676. //
  677. //    HAL_DoOpenSession
  678. //
  679. //    Process an OpenDriver request to the stub drivers
  680. //
  681. /************************************************************************************/
  682.  
  683. OSErr HAL_DoOpenSession(void)
  684. {
  685.  
  686.     OSErr        err;
  687.     LineParms    Line_Coding;
  688.     
  689.     TraceMessage(0,"\pEntering HAL_DoOpenSession");
  690.     
  691.     // only allow one open session
  692.     
  693.     if (gGlobals->openSession)
  694.         return openErr;
  695.         
  696.     //    reset internal indexes, buffers, etc.
  697.     
  698.     err = HAL_SetInputBuffer(nil, 0);
  699.     if (err)
  700.         return openErr;
  701.     
  702.     //  since we've cleared the buffer to zero initially we have to explicitly
  703.     //  initialize the baudRate
  704.     
  705.     gGlobals->baudRate = kMaxBaudRate;
  706.     
  707.     //    reset default values for other variables
  708.  
  709.     gGlobals->xOnOffChar = 0;
  710.     gGlobals->peChar = 0;
  711.     gGlobals->peAltChar = 0;
  712.  
  713.     //    reset handshake default values as per scc serial driver
  714.  
  715.     gGlobals->serShk.fXOn = 0;
  716.     gGlobals->serShk.fCTS = 1;
  717.     gGlobals->serShk.xOn = 0;
  718.     gGlobals->serShk.xOff = 0;
  719.     gGlobals->serShk.evts = 0;
  720.     gGlobals->serShk.fInX = 0;
  721.     gGlobals->serShk.fDTR = 1;
  722.  
  723.     //    reset serial status record
  724.  
  725.     gGlobals->serStat.cumErrs = 0;
  726.     gGlobals->serStat.xOffSent = 0;
  727.     gGlobals->serStat.rdPend = 0;
  728.     gGlobals->serStat.wrPend = 0;
  729.     gGlobals->serStat.ctsHold = 0;
  730.     gGlobals->serStat.xOffHold = 0;
  731.     
  732.     // Line coding structure
  733.     
  734.     Line_Coding.DTERate1 = 0;            // gets handled later with
  735.     Line_Coding.DTERate2 = 0;            // value from gGlobals->baudRate
  736.     Line_Coding.CharFormat = k1StopBit;
  737.     Line_Coding.ParityType = kNoParity;
  738.     Line_Coding.DataBits = k8DataBits;
  739.     
  740.     InitLineCoding(Line_Coding);
  741.     
  742.     //    Let's get started
  743.     
  744.     HAL_EnableSerialDevice();
  745.     
  746.     // we now have an open session
  747.     
  748.     gGlobals->openSession = true;
  749.         
  750.     return noErr;
  751. }
  752.  
  753. /************************************************************************************/
  754. //
  755. //    HAL_DoCloseSession
  756. //
  757. //    Process a CloseDriver request to the stub drivers
  758. //
  759. /************************************************************************************/
  760.  
  761. OSErr HAL_DoCloseSession(void)
  762. {
  763.  
  764.     TraceMessage(0,"\pEntering HAL_DoCloseSession");
  765.  
  766.     HAL_DisableSerialDevice();
  767.             
  768.     //    reset internal indexes, buffers, etc. - this
  769.     //    is important for vm to unhold memory on any
  770.     //    buffer the client may have requested earlier
  771.     
  772.     HAL_SetInputBuffer(nil, 0);
  773.                     
  774.     // we no longer have an open session
  775.         
  776.     gGlobals->openSession = false;
  777.  
  778.     return noErr;
  779. }
  780.  
  781. /************************************************************************************/
  782. //
  783. //    HAL_ControlExtend
  784. //
  785. //    User extensions to control
  786. //
  787. /************************************************************************************/
  788.  
  789. OSErr HAL_ControlExtend(ParmBlkPtr pb)
  790. {
  791.  
  792.     TraceMessage(0,"\pEntering HAL_ControlExtend");
  793.  
  794.     if (pb->cntrlParam.csCode == kpciGetDCD)
  795.     {
  796.         ((char *)(pb->cntrlParam.csParam))[6] = USBGetDCDValue();
  797.         return noErr;
  798.     }
  799.     
  800.     return controlErr;
  801. }
  802.  
  803. /************************************************************************************/
  804. //
  805. //    HAL_StatusExtend
  806. //
  807. //    User extensions to status
  808. //
  809. /************************************************************************************/
  810.  
  811. OSErr HAL_StatusExtend(ParmBlkPtr pb)
  812. {
  813. #pragma unused (pb)
  814.  
  815.     TraceMessage(0,"\pEntering HAL_StatusExtend");
  816.     
  817.     return statusErr;
  818. }
  819.  
  820.  
  821. /************************************************************************************/
  822. //
  823. //    HAL_ShimInput
  824. //
  825. //    Handles the coordination of input and the requestors buffer.
  826. //
  827. /************************************************************************************/
  828.  
  829. void HAL_ShimInput(UInt8 *buf, UInt32 count)
  830. {
  831.     IOParam                 *pb;
  832.     OSErr                    result;
  833.     register UInt16            nextIndex;
  834.     register unsigned char    rcvByte;
  835.     unsigned char            cumErrs;
  836.     
  837.     TraceMessage(0,"\pEntering ShimInput");
  838.         
  839.     //    set return result to incomplete
  840.  
  841.     result = 1;
  842.     cumErrs = 0;
  843.  
  844.     while (count--)
  845.     {
  846.  
  847.         //  handle reading of data available in the hardware receive buffer
  848.         
  849.         rcvByte = *buf++;
  850.                             
  851.         //    compute index into our input buffer
  852.  
  853.         nextIndex = gGlobals->inBufEndIndex + 1;
  854.         if ( nextIndex >= gGlobals->inBufLen ) 
  855.             nextIndex = 0;
  856.             
  857.         //    stuff the character into the input buffer and update the index
  858.  
  859.         gGlobals->inBufPtr[gGlobals->inBufEndIndex] = rcvByte;
  860.         gGlobals->inBufEndIndex = nextIndex;
  861.  
  862.         //    check for input buffer overflow
  863.  
  864.         if (gGlobals->inBufEndIndex == gGlobals->inBufStartIndex)
  865.         {
  866.             //    mark that we've had an overrun
  867.  
  868.             gGlobals->serStat.cumErrs |= swOverrunErr;
  869.             cumErrs |= swOverrunErr;
  870.                 
  871.             //    drop oldest character from our internal buffer
  872.  
  873.             gGlobals->inBufStartIndex++;
  874.             if (gGlobals->inBufStartIndex >= gGlobals->inBufLen)
  875.                 gGlobals->inBufStartIndex = 0;
  876.                 
  877.             //    we've had a software overrun -- we quit now and let the
  878.             //    client get a chance to read in the existing bytes -- 
  879.         }
  880.         
  881.         //    check for an outstanding read request
  882.         
  883.         pb = (IOParam *)gGlobals->pbIn;
  884.         if (pb)
  885.         {
  886.             //    copy bytes from input buffer into pb read buffer
  887.             //    (result is either 1=incomplete or 0=complete)
  888.     
  889.             result = HAL_FillReadRequest(pb);
  890.             
  891.             //    handle errors that cause read aborts
  892.             
  893.             if (cumErrs & gGlobals->serShk.errs) 
  894.                 result = rcvrErr;
  895.             
  896.             //    if we have fulfilled this read request, we
  897.             //  need to call IOCommandIsComplete on it
  898.             //  and continue processing with the next request
  899.             
  900.             if ( result <= noErr )
  901.             {
  902.                 gGlobals->pbIn = nil;
  903.                     // clean up after ourselves
  904.                 ShimIOComplete((union ParamBlockRec *)pb, result);
  905. //                break;  // correction to original sample code 11/2/98
  906.             }
  907.         }
  908.     }
  909.     
  910. //    // clean up after ourselves        // moved ShimIOComplete to above
  911. //    if (result <= noErr)            // correction to original sample code 11/2/98
  912. //        ShimIOComplete((union ParamBlockRec *)pb, result);
  913. }